package com.demo2do.fms.scheduler.scheduler;

import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.fms.entity.report.AppointmentStatus;
import com.demo2do.fms.scheduler.entity.appointment.DriverCostAppointment;
import com.demo2do.fms.scheduler.entity.appointment.DriverMileageAppointment;
import com.demo2do.fms.scheduler.entity.appointment.TransportRevenueAppointment;
import com.demo2do.fms.scheduler.entity.appointment.VehicleMileageAppointment;
import com.demo2do.fms.scheduler.service.AppointmentReader;
import com.demo2do.fms.scheduler.service.AppointmentWriter;

/**
 *
 * @author Ark
 *
 */
@Component("appointmentScheduler")
public class AppointmentScheduler {

    private static final Logger logger = LoggerFactory.getLogger(AppointmentScheduler.class);
    
    @Autowired
    private AppointmentReader appointmentReader;
    
    @Autowired
    private AppointmentWriter appointmentWriter;
    
    /**
     * audit appointment
     */
    public void audit() {
        
        logger.warn("#audit() - start...");
        
        String today = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
        
        List<VehicleMileageAppointment> vmAppointments = appointmentReader.listVehicleMileage(AppointmentStatus.AUDITING, today);
        if (CollectionUtils.isNotEmpty(vmAppointments)) {
            for (VehicleMileageAppointment appointment : vmAppointments) {
                appointmentWriter.auditVehicleMileage(appointment);
            }
        }
        
        List<DriverMileageAppointment> dmAppointments = appointmentReader.listDriverMileage(AppointmentStatus.AUDITING, today);
        if (CollectionUtils.isNotEmpty(dmAppointments)) {
            for (DriverMileageAppointment appointment : dmAppointments) {
                appointmentWriter.auditDriverMileage(appointment);
            }
        }
        
        List<TransportRevenueAppointment> trAppointments = appointmentReader.listTransportRevenue(AppointmentStatus.AUDITING, today);
        if (CollectionUtils.isNotEmpty(trAppointments)) {
            for (TransportRevenueAppointment appointment : trAppointments) {
                appointmentWriter.auditTransportRevenue(appointment);
            }
        }
        
        List<DriverCostAppointment> dcAppointments = appointmentReader.listDriverCost(AppointmentStatus.AUDITING, today);
        if (CollectionUtils.isNotEmpty(dcAppointments)) {
            for (DriverCostAppointment appointment : dcAppointments) {
                appointmentWriter.auditDriverCost(appointment);
            }
        }
        
        logger.warn("#audit() - end...");
        
    }
    
    /**
     * expire appointment
     */
    public void expire() {
        
        logger.warn("#expire() - start...");
        
        Date threeDaysAgo = DateUtils.addDays(new Date(), -3);
        
        List<VehicleMileageAppointment> vmAppointments = appointmentReader.listExpiredVehicleMileage(AppointmentStatus.COMPLETED, threeDaysAgo);
        if (CollectionUtils.isNotEmpty(vmAppointments)) {
            for (VehicleMileageAppointment appointment : vmAppointments) {
                appointmentWriter.expireVehicleMileage(appointment);
            }
        }
        
        List<DriverMileageAppointment> dmAppointments = appointmentReader.listExpiredDriverMileage(AppointmentStatus.COMPLETED, threeDaysAgo);
        if (CollectionUtils.isNotEmpty(dmAppointments)) {
            for (DriverMileageAppointment appointment : dmAppointments) {
                appointmentWriter.expireDriverMileage(appointment);
            }
        }
        
        List<TransportRevenueAppointment> trAppointments = appointmentReader.listExpiredTransportRevenue(AppointmentStatus.COMPLETED, threeDaysAgo);
        if (CollectionUtils.isNotEmpty(trAppointments)) {
            for (TransportRevenueAppointment appointment : trAppointments) {
                appointmentWriter.expireTransportRevenue(appointment);
            }
        }
        
        List<DriverCostAppointment> dcAppointments = appointmentReader.listExpireDriverCost(AppointmentStatus.COMPLETED, threeDaysAgo);
        if (CollectionUtils.isNotEmpty(dcAppointments)) {
            for (DriverCostAppointment appointment : dcAppointments) {
                appointmentWriter.expireDriverCost(appointment);
            }
        }
        
        logger.warn("#expire() - end...");
        
    }
    
    /**
     * handle vehicle mileage appointment
     */
    public void exportVehicleMileage() {
        
        logger.info("#exportVehicleMileage() - start...");
        
        String yesterday = DateFormatUtils.format(DateUtils.addDays(new Date(), -1), "yyyy-MM-dd");
        List<VehicleMileageAppointment> appointments = appointmentReader.listVehicleMileage(AppointmentStatus.PENDING, yesterday);
        if (CollectionUtils.isEmpty(appointments)) {
            logger.info("#exportVehicleMileage() - appointments is empty...");
        }
        
        for (VehicleMileageAppointment appointment : appointments) {
            appointmentWriter.startVehicleMileage(appointment);
            appointmentWriter.exportVehicleMileage(appointment);
        }
        
        logger.info("#exportVehicleMileage() - end...");
        
    }
    
    /**
     * handle driver mileage appointment
     */
    public void exportDriverMileage() {
        
        logger.info("#exportDriverMileage() - start...");
        
        String yesterday = DateFormatUtils.format(DateUtils.addDays(new Date(), -1), "yyyy-MM-dd");
        List<DriverMileageAppointment> appointments = appointmentReader.listDriverMileage(AppointmentStatus.PENDING, yesterday);
        if (CollectionUtils.isEmpty(appointments)) {
            logger.info("#exportDriverMileage() - appointments is empty...");
        }
        
        for (DriverMileageAppointment appointment : appointments) {
            appointmentWriter.startDriverMileage(appointment);
            appointmentWriter.exportDriverMileage(appointment);
        }
        
        logger.info("#exportDriverMileage() - start...");
        
    }
    
    /**
     * handle transport revenue
     */
    public void exportTransportRevenue() {
        
        logger.info("#exportTransportRevenue() - start...");
        
        String yesterday = DateFormatUtils.format(DateUtils.addDays(new Date(), -1), "yyyy-MM-dd");
        List<TransportRevenueAppointment> appointments = appointmentReader.listTransportRevenue(AppointmentStatus.PENDING, yesterday);
        if (CollectionUtils.isEmpty(appointments)) {
            logger.info("#exportTransportRevenue() - appointments is empty...");
        }
        logger.info("#exportTransportRevenue() - the appointments size is [{}], and the yesterday is [{}]", appointments.size(), yesterday);
        for (TransportRevenueAppointment appointment : appointments) {
            appointmentWriter.startTransportRevenue(appointment);
            appointmentWriter.exportTransportRevenue(appointment);
        }
        
        logger.info("#exportTransportRevenue() - end...");
        
    }
    
    /**
     * handle driver cost appointment
     */
    public void exportDriverCost() {
        
        logger.info("#exportDriverCost() - start...");
        
        String yesterday = DateFormatUtils.format(DateUtils.addDays(new Date(), -1), "yyyy-MM-dd");
        List<DriverCostAppointment> appointments = appointmentReader.listDriverCost(AppointmentStatus.PENDING, yesterday);
        if (CollectionUtils.isEmpty(appointments)) {
            logger.info("#exportDriverCost() - appointments is empty...");
        }
        
        for (DriverCostAppointment appointment : appointments) {
            appointmentWriter.startDriverCost(appointment);
            appointmentWriter.exportDriverCost(appointment);
        }
        
        logger.info("#exportDriverCost() - start...");
        
    }
    
}
